package org.dreamwork.plugins.jboss.vfs;

import org.dreamwork.util.IClassFilter;
import org.dreamwork.util.IURLFetcher;
import org.dreamwork.util.ReferenceUtil;
import org.jboss.virtual.VirtualFile;
import org.jboss.virtual.plugins.context.zip.ZipEntryContext;
import org.jboss.virtual.plugins.context.zip.ZipEntryHandler;
import org.jboss.virtual.plugins.vfs.VirtualFileURLConnection;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: seth.yang
 * Date: 13-7-30
 * Time: 下午6:14
 */
public class VFSURLFetcher implements IURLFetcher {
    public List<Class<?>> fetchClasses (String packageName, URL url, ClassLoader loader, IClassFilter filter) throws Exception {
        List<Class<?>> list = new ArrayList<Class<?>> ();
        VirtualFileURLConnection conn = (VirtualFileURLConnection) url.openConnection ();
        for (VirtualFile vf : conn.getContent ().getChildren ()) {
            if (filter == null || filter.accept (vf.getPathName ())) {
                String name = vf.getName ();
                if (!name.endsWith (".class")) continue;
                name = name.substring (0, name.length () - 6);
                String className = packageName + '.' + name;
                list.add (loader.loadClass (className));
            }
        }
        return list;
    }

    @Override
    public File getPhysicalFile (URL url) throws IOException, URISyntaxException {
        try {
            boolean isWindows = System.getProperty ("os.name").toLowerCase ().contains ("windows");
            VirtualFileURLConnection conn = (VirtualFileURLConnection) url.openConnection ();
            VirtualFile vf = conn.getContent ();
            ZipEntryHandler handler = (ZipEntryHandler) ReferenceUtil.get (vf, "handler");
            if (handler == null) return null;
            ZipEntryContext context = (ZipEntryContext) ReferenceUtil.get (handler, "context");
            if (context == null) return null;
            String filePath = (String) ReferenceUtil.get (context, "filePath");
            if (filePath == null) return null;
            if (isWindows && filePath.charAt (0) == '/') filePath = filePath.substring (1);
            return new File (URLDecoder.decode (filePath, ENCODING));
        } catch (Exception ex) {
            ex.printStackTrace ();
        }
        return null;
    }
}